package cube.data;

import cube.data.util.SLIP;
import cube.utils.TimeUtil;

/**
 * SLIP帧缓冲区
 * 
 * @author abiao
 */
public class SLIPBuffer {

    /**
     * SLIP帧标记
     */
    private static final byte END = (byte) 0xc0;

    /**
     * 环形队列缓冲区
     */
    private RingBuffer buff;

    /**
     * SLIP帧缓冲区
     */
    public SLIPBuffer(int size) {
        buff = new RingBuffer(size);
    }

    /**
     * 将封帧后的数据放入缓冲区
     */
    public void put(byte[] data) {
        buff.put(data);
    }

    /**
     * 从缓冲区中取出解帧后的数据
     */
    public synchronized byte[] get() {
        return SLIP.unseal(getSLIP());
    }

    /**
     * 获取SLIP帧
     */
    private byte[] getSLIP() {
        int head;
        while ((head = buff.index(END, 1)) == -1) {
            TimeUtil.blockPeriod();
        }
        while (head > 0) {
            buff.get(head);
            head = buff.index(END);
        }
        int tail;
        while ((tail = buff.index(END, 2)) <= head + 1) {
            if (tail == head + 1) {
                buff.get(1);
            } else if (tail == -1) {
                TimeUtil.blockPeriod();
            }
        }
        return buff.get(tail + 1);
    }
}
